; Copyright 2013 padnest@gmail.com

; Licensed under the Apache License, Version 2.0 (the "License");
; you may not use this file except in compliance with the License.
; You may obtain a copy of the License at
;
;   http://www.apache.org/licenses/LICENSE-2.0
;
; Unless required by applicable law or agreed to in writing, software
; distributed under the License is distributed on an "AS IS" BASIS,
; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
; See the License for the specific language governing permissions and
; limitations under the License.

intServiceRoutine				; max 56 cycles
isr_save_all					; 4 cycles
	movwf 	ISR_W				; save W (in the curent bank)
	swapf 	STATUS, W 			; save STATUS (without affecting it)
	bank0
	movwf 	ISR_STATUS

isr_tmr0						; 8 to 11 cycles
	movlf   D'176', TMR0        ; reload TMR0 (80 *1us = 80us): leave 80 - 56 = 24 free cycles for main loop

	movf    PWM_COUNT, F		; if pwm counter <> 0
	btfss   STATUS, Z
	goto	isr_pwm0_check		; go to check
	clrf	PORTB				; else put all pwm channels low
	movlf	0x80, PWM_COUNT		; reset PWM_COUNTER

	movf    COUNTER, F			; if COUNTER > 0
	btfss   STATUS, Z
	decf	COUNTER				; decrement loop counter

isr_pwm0_check					; 4 cycles (4*8 ch = 32 cycles) in every condition
	movf    PWM_COUNT, W        ; compare PWM REG value
    subwf   PWM_REG + 0, W		; W = PWM_REG - PWM_COUNT
    btfsc   STATUS, C			; if PWM_COUNT > PWM_REG (C=0) skip (keep low)
    bsf     PWM_CH0				; else keep high
isr_pwm1_check
	movf    PWM_COUNT, W
    subwf   PWM_REG + 1, W
    btfsc   STATUS, C
    bsf     PWM_CH1
isr_pwm2_check
	movf    PWM_COUNT, W
    subwf   PWM_REG + 2, W
    btfsc   STATUS, C
    bsf     PWM_CH2
isr_pwm3_check
	movf    PWM_COUNT, W
    subwf   PWM_REG + 3, W
    btfsc   STATUS, C
    bsf     PWM_CH3
isr_pwm4_check
	movf    PWM_COUNT, W
    subwf   PWM_REG + 4, W
    btfsc   STATUS, C
    bsf     PWM_CH4
isr_pwm5_check
	movf    PWM_COUNT, W
    subwf   PWM_REG + 5, W
    btfsc   STATUS, C
    bsf     PWM_CH5
isr_pwm6_check
	movf    PWM_COUNT, W
    subwf   PWM_REG + 6, W
    btfsc   STATUS, C
    bsf     PWM_CH6
isr_pwm7_check
	movf    PWM_COUNT, W
    subwf   PWM_REG + 7, W
    btfsc   STATUS, C
    bsf     PWM_CH7

isr_tmr0_end					; 2 cycles
	decf	PWM_COUNT			; decrement counter (0x80 to 0x00)
	bcf     INTCON, T0IF		; clear TRM0 interrupt flag

isr_recovery					; 7 cycles
	bank0
	swapf 	ISR_STATUS, W 		; restore STATUS (and the original bank)
	movwf 	STATUS 				;
	swapf 	ISR_W, F 			; restore W (from the original bank)
	swapf 	ISR_W, W 			;
	retfie
